#include <iostream>
#include <stdexcept>
using namespace std;
class ArrayQueue {
private:
    int* data;
    int front;
    int rear;
    int capacity;
    int size;
public:
    ArrayQueue(int cap) : capacity(cap), front(0), rear(0), size(0) {
        data = new int[capacity];
    }
    ~ArrayQueue() {
        delete[] data;
    }
    void enqueue(int value) {
        if (isFull()) throw runtime_error("Queue is full");
        data[rear] = value;
        rear = (rear + 1) % capacity;
        size++;
    }
    int dequeue() {
        if (isEmpty()) throw runtime_error("Queue is empty");
        int value = data[front];
        front = (front + 1) % capacity;
        size--;
        return value;
    }
    int getFront() const {
        if (isEmpty()) throw runtime_error("Queue is empty");
        return data[front];
    }
    int getRear() const {
        if (isEmpty()) throw runtime_error("Queue is empty");
        return data[(rear - 1 + capacity) % capacity];
    }
    bool isEmpty() const {
        return size == 0;
    }
    bool isFull() const {
        return size == capacity;
    }
    void print() const {
        cout << "Queue: [";
        for (int i = 0, idx = front; i < size; i++) {
            cout << data[idx];
            if (i < size - 1) cout << ", ";
            idx = (idx + 1) % capacity;
        }
        cout << "]" << endl;
    }
};
  
int main() {
    ArrayQueue q(5);
    q.enqueue(10);
    q.enqueue(20);
    q.enqueue(30);
    q.print();

    cout << "Front: " << q.getFront() << endl; // 10
    cout << "Rear: " << q.getRear() << endl;   // 30

    q.dequeue();
    q.enqueue(40);
    q.enqueue(50);
    q.print();

    return 0;
}
